package com.scs.application.modules.sys.service.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.scs.application.core.exception.BusinessException;
import com.scs.application.core.service.BaseServiceImpl;
import com.scs.application.core.utils.CacheUtils;
import com.scs.application.modules.sys.dto.FlowDTO;
import com.scs.application.modules.sys.entity.Flow;
import com.scs.application.modules.sys.entity.FlowButton;
import com.scs.application.modules.sys.entity.FlowNode;
import com.scs.application.modules.sys.mapper.FlowButtonMapper;
import com.scs.application.modules.sys.mapper.FlowMapper;
import com.scs.application.modules.sys.mapper.FlowNodeMapper;
import com.scs.application.modules.sys.service.FlowService;
import com.google.common.collect.Lists;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.Serializable;
import java.util.Collection;
import java.util.List;

/**
 * <p>
 * 服务实现类
 * </p>
 */
@Service
public class FlowServiceImpl extends BaseServiceImpl<FlowMapper, Flow> implements FlowService {


    @Autowired
    private FlowNodeMapper flowNodeMapper;

    @Autowired
    private FlowButtonMapper flowButtonMapper;

    @Override
    public boolean removeCascadeByIds(Collection<? extends Serializable> idList) {
        flowNodeMapper.delete(Wrappers.<FlowNode>query().in("flow_id", idList));
        flowButtonMapper.delete(Wrappers.<FlowButton>query().in("flow_id", idList));
        CacheUtils.clearCache(CacheUtils.FLOW_NODE_CACHE);
        CacheUtils.clearCache(CacheUtils.FLOW_BUTTON_CACHE);
        return super.removeCascadeByIds(idList);
    }

    @Override
    public Flow findByFlowKey(String flowKey) {
        return this.getOne(
                Wrappers.<Flow>query().eq("code", flowKey).last("limit 1")
        );
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Flow copy(String flowKey) {
        Flow flow = findByFlowKey(flowKey);
        if (flow == null) {
            throw new BusinessException("流程不存在，复制失败");
        }
        Flow copyFlow = new Flow();

        copyFlow.setId(null);
        copyFlow.setCode(flowKey + "-copy");
        copyFlow.setName(flow.getName() + "-副本");
        copyFlow.setFieldName(flow.getFieldName());
        copyFlow.setFlagDisable(flow.getFlagDisable());
        copyFlow.setRemark(flowKey + "流程副本");

        this.save(copyFlow);

        List<FlowNode> flowNodes = flowNodeMapper.selectList(Wrappers.<FlowNode>query().eq("flow_id", flow.getId()));
        for (FlowNode flowNode : flowNodes) {
            FlowNode copyFlowNode = new FlowNode();
            BeanUtils.copyProperties(flowNode, copyFlowNode);
            copyFlowNode.setFlowId(copyFlow.getId()).setId(null);
            flowNodeMapper.insert(copyFlowNode);
        }

        List<FlowButton> flowButtons = flowButtonMapper.selectList(Wrappers.<FlowButton>query().eq("flow_id", flow.getId()));
        for (FlowButton flowButton : flowButtons) {
            FlowButton copyFlowButton = new FlowButton();
            BeanUtils.copyProperties(flowButton, copyFlowButton);
            copyFlowButton.setFlowId(copyFlow.getId()).setId(null);
            flowButtonMapper.insert(copyFlowButton);
        }
        return copyFlow;
    }

    /**
     * 根据flowId获取flow实体类
     * @param flowId
     * @return
     */
    @Override
    public FlowDTO getFlowDTOById(String flowId) {
        Flow flow = this.getById(flowId);
        if (flow == null) {
            return null;
        }
        return getFlowDTO(flow);
    }
    /**
     * 根据flowCode获取flow实体类
     * @param flowCode
     * @return
     */
    @Override
    public FlowDTO getFlowDTOByCode(String flowCode) {
        Flow flow = this.getOne(Wrappers.<Flow>query().eq("code", flowCode).last("limit 1"));
        if (flow == null) {
            return null;
        }
        return getFlowDTO(flow);
    }

    private FlowDTO getFlowDTO(Flow flow) {
        List<FlowButton> flowButtons = flowButtonMapper.selectList(Wrappers.<FlowButton>query().eq("flow_id", flow.getId()));

        FlowDTO flowDTO = new FlowDTO();
        BeanUtils.copyProperties(flow, flowDTO);

        if (flowButtons != null && !flowButtons.isEmpty()) {
            flowDTO.setFlowButtons(Lists.newArrayListWithCapacity(flowButtons.size()));
            for(FlowButton flowButton : flowButtons) {
                FlowDTO.FlowButtonDTO flowButtonDTO = new FlowDTO.FlowButtonDTO();
                BeanUtils.copyProperties(flowButton, flowButtonDTO);
                flowDTO.getFlowButtons().add(flowButtonDTO);
            }
        }

        List<FlowNode> flowNodes = flowNodeMapper.selectList(Wrappers.<FlowNode>query().eq("flow_id", flow.getId()));

        if (flowNodes != null && !flowNodes.isEmpty()) {
            flowDTO.setFlowNodes(Lists.newArrayListWithCapacity(flowNodes.size()));
            for(FlowNode flowNode : flowNodes) {
                FlowDTO.FlowNodeDTO flowNodeDTO = new FlowDTO.FlowNodeDTO();
                BeanUtils.copyProperties(flowNode, flowNodeDTO);
                flowDTO.getFlowNodes().add(flowNodeDTO);
            }
        }
        return flowDTO;
    }

    /**
     * 获取DTOList
     * @return
     */
    public List<FlowDTO> getDTOList() {
        return null;
    }

    @Override
    public Boolean isSupport(Boolean flagProject) {
        return flagProject;
    }

}
